import type { DownloadArgs, RendererHttpInvoker } from "@common/ipc-types.ts";
import { ipcInvoker } from "./electron.ts";
import type { DownloadCompleteArgs, DownloadErrorArgs, DownloadParam, DownloadProgressArgs } from "@common/http-types.ts";

export const httpInvoker: RendererHttpInvoker = {
  get(url, options) {
    return ipcInvoker.invoke("http.get", url, options);
  },
  getText(url, options) {
    return ipcInvoker.invoke("http.getText", url, options);
  },
  getJson(url, options) {
    return ipcInvoker.invoke("http.getJson", url, options);
  },
  post(url, options) {
    return ipcInvoker.invoke("http.post", url, options);
  },
  postText(url, body, options) {
    return ipcInvoker.invoke("http.postText", url, body, options);
  },
  postJson(url, body, options) {
    return ipcInvoker.invoke("http.postJson", url, body, options);
  },

  downloadFile(param: DownloadParam) {
    ipcInvoker.send("http.download", param);
  },

  download(args: DownloadArgs): Promise<DownloadCompleteArgs> {
    return new Promise<DownloadCompleteArgs>(async (resolve, reject) => {
      ipcInvoker.send("http.download", { ...args, progress: undefined } as DownloadArgs);
      const id = args.id!;

      const onProgress = (pargs: DownloadProgressArgs) => args.progress?.(pargs);

      const onError = (args: DownloadErrorArgs) => {
        reject(`下载失败: ${args.message}`);
        unsubscribe();
      };
      const onComplete = (args: DownloadCompleteArgs) => {
        resolve(args);
        unsubscribe();
      };

      const id0 = ipcInvoker.on(`file.download.progress.${id}`, onProgress);
      const id1 = ipcInvoker.on(`file.download.error.${id}`, onError);
      const id2 = ipcInvoker.on(`file.download.complete.${id}`, onComplete);

      function unsubscribe() {
        ipcInvoker.off(`file.download.progress.${id}`, id0);
        ipcInvoker.off(`file.download.complete.${id}`, id1);
        ipcInvoker.off(`file.download.error.${id}`, id2);
      }
    });
  },

  cancelDownload(id: string) {
    ipcInvoker.send("http.download.cancel", id);
  },
};
